// filename: frontend/src/components/SongCard/SongCard.vue

<template>
  <div class="song-card-wrapper">

    <AddToPlaylistModal 
      v-if="isAddToPlaylistModalVisible" 
      :song-id="song.id"
      @close="isAddToPlaylistModalVisible = false" 
    />

    <CommentModal
      v-if="isCommentModalVisible"
      target-type="song"
      :target-id="song.id"
      :highlight-parent-id="highlightParentId"
      :highlight-comment-id="highlightCommentId"
      @close="handleCommentModalClose"
    />

    <div class="song-card" :class="{ 'disabled': isEditMode }">
      <view class="cover-wrapper" @click="handlePlayClick" :class="{ active: isActive }">
        <image
          class="song-cover"
          :src="song.cover_art_url ? song.cover_art_url : '/static/placeholder.jpg'"
          alt="cover"
          mode="aspectFill"
        />
        <view class="play-icon-wrapper">
          <view v-if="isActive && playerStore.isPlaying" class="sound-wave-icon">
            <span></span>
            <span></span>
            <span></span>
          </view>
          <svg v-else xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="white"><path d="M8 5v14l11-7z"/></svg>
        </view>
      </view>

      <div class="song-info">
        <h3 class="title">{{ song.title }}</h3>
        <p class="artist-line">
          <span>翻唱: {{ song.cover_artists || 'N/A' }}</span>
          <span class="artist-separator"></span>
          <span>原唱: {{ song.original_artists || 'N/A' }}</span>
        </p>
        <p class="meta">
          <span>{{ song.language_name || 'N/A' }}</span>
          <span>•</span>
          <span>{{ song.status_name || 'N/A' }}</span>
          <span>•</span>
          <span>{{ formattedDate }}</span>
        </p>
      </div>

      <div class="actions">
        <div class="action-item like-btn" @click.stop="handleLikeClick">
          <svg v-if="isLiked" class="like-icon liked" width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
            <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/>
          </svg>
          <svg v-else class="like-icon" width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
            <path d="M16.5 3c-1.74 0-3.41.81-4.5 2.09C10.91 3.81 9.24 3 7.5 3 4.42 3 2 5.42 2 8.5c0 3.78 3.4 6.86 8.55 11.54L12 21.35l1.45-1.32C18.6 15.36 22 12.28 22 8.5 22 5.42 19.58 3 16.5 3zm-4.4 15.55l-.1.1-.1-.1C7.14 14.24 4 11.39 4 8.5 4 6.5 5.5 5 7.5 5c1.54 0 3.04.99 3.57 2.36h1.87C13.46 5.99 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 5.74-7.9 10.05z"/>
          </svg>
          <span class="likes-count">{{ localLikesCount }}</span>
        </div>
      </div>

      <div class="menu-button" @click.stop="toggleMenu">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="24" height="24">
          <path d="M12 3c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"></path>
        </svg>
      </div>
    </div>

    <div v-if="isMenuOpen" class="filter-menu" @click.stop>
      <div class="menu-header">筛选标签</div>
      <div class="menu-item download-item" @click="downloadSongs([song.id])">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/></svg>
        <span>下载这首歌</span>
      </div>
      <div class="menu-item share-item" @click="shareSong">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3s3-1.34 3-3-1.34-3-3-3z"/></svg>
        <span>转发分享</span>
      </div>
      <div class="menu-item add-to-playlist-item" @click="openAddToPlaylistModal">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M14 10H2v2h12v-2zm0-4H2v2h12V6zm4 8v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zM2 16h8v-2H2v2z"/></svg>
        <span>添加到歌单</span>
      </div>
      <div class="menu-item comment-item" @click="openCommentModal">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M21.99 4c0-1.1-.89-2-1.99-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4-.01-18zM18 14H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/></svg>
        <span>评论 ({{ song.comments_count || 0 }})</span>
      </div>
      <checkbox-group @change="onCheckboxChange" class="tags-container">
        <label v-for="tag in filterableTags" :key="tag.value" class="tag-item">
          <checkbox :value="tag.value" :checked="selectedTags.includes(tag.value)" class="tag-checkbox" />
          <span class="tag-text">{{ tag.display }}</span>
        </label>
      </checkbox-group>
    </div>
  </div>
</template>

<script setup>
import { computed, defineEmits, defineExpose, defineProps, ref, onMounted } from "vue";
import { usePlayerStore } from "@/store/player";
import { downloadSongs } from "@/utils/download.js";
import { useAuthStore } from "@/store/auth";
import { request } from "@/utils/request"; // 【核心修改1】导入 request
import AddToPlaylistModal from "@/components/AddToPlaylistModal/AddToPlaylistModal.vue";
import CommentModal from "@/components/CommentModal/CommentModal.vue";

const props = defineProps({
  song: { type: Object, required: true },
  isEditMode: { type: Boolean, default: false }
});
const emit = defineEmits(["filter", "menuToggled", "play", "refresh-request"]); 

const playerStore = usePlayerStore();
const authStore = useAuthStore();

const isMenuOpen = ref(false);
const isAddToPlaylistModalVisible = ref(false);
const isCommentModalVisible = ref(false);
const highlightParentId = ref(null);
const highlightCommentId = ref(null);
const selectedTags = ref([]);
const initialSearchKeywords = ref([]);
const isLiked = ref(props.song.liked_by_user);
const localLikesCount = ref(props.song.likes_count);

const isActive = computed(() => playerStore.currentSong?.id === props.song.id);

const handleCommentModalClose = () => {
  isCommentModalVisible.value = false;
  emit('refresh-request', { songId: props.song.id });
};

const handlePlayClick = () => {
  if (props.isEditMode) return;
  if (isActive.value) {
    playerStore.togglePlay();
  } else {
    emit("play", props.song.id);
  }
};

// --- 【核心修改2】重写 handleLikeClick ---
const handleLikeClick = async () => {
  if (props.isEditMode) return;
  if (!authStore.isLoggedIn) {
    uni.showToast({ title: "请先登录", icon: "none" });
    return;
  }
  
  // 乐观更新 UI
  const originalIsLiked = isLiked.value;
  isLiked.value = !isLiked.value;
  localLikesCount.value += isLiked.value ? 1 : -1;

  try {
    const data = await request({
      url: `/api/songs/${props.song.id}/like`,
      method: isLiked.value ? 'POST' : 'DELETE'
    });
    
    // 使用后端返回的最新数据同步状态
    isLiked.value = data.liked_by_user;
    localLikesCount.value = data.likes_count;

  } catch (error) {
    // 请求失败，回滚 UI
    isLiked.value = originalIsLiked;
    localLikesCount.value += originalIsLiked ? 1 : -1;
    // 如果是 token 过期等问题，request 工具会自动处理，这里无需额外提示
    // 如果是其他服务器错误，可以给一个通用提示
    if (error.statusCode !== 401) {
        uni.showToast({ title: "操作失败", icon: "error" });
    }
  }
};


// --- 其他函数保持不变 ---
const toggleMenu = () => {
  if (props.isEditMode) return;
  isMenuOpen.value = !isMenuOpen.value;
  if (isMenuOpen.value) {
    const currentGlobalSearch = document.querySelector(".search-input")?.value || "";
    initialSearchKeywords.value = currentGlobalSearch.split(" ").filter(Boolean);
    selectedTags.value = filterableTags.value
      .filter((tag) => initialSearchKeywords.value.includes(tag.value))
      .map((tag) => tag.value);
  }
  emit("menuToggled", { id: props.song.id, isOpen: isMenuOpen.value });
};

const onCheckboxChange = (event) => {
  const newSelection = event.detail.value;
  selectedTags.value = newSelection;
  const combined = [...initialSearchKeywords.value, ...newSelection];
  const uniqueKeywords = [...new Set(combined)];
  const searchTerm = uniqueKeywords.join(" ");
  emit("filter", searchTerm);
};

const formattedDate = computed(() =>
  formatDateWithWeekday(props.song.cover_date)
);

const filterableTags = computed(() => {
  const tags = [];
  const addTag = (displayValue, searchValue) => {
    const actualSearchValue = searchValue || displayValue;
    if (displayValue) tags.push({ display: `筛选「${displayValue}」`, value: actualSearchValue });
  };
  const addArtistTags = (artistsString) => {
    if (artistsString) artistsString.split(",").forEach((artist) => addTag(artist.trim()));
  };
  addTag(props.song.title);
  addArtistTags(props.song.cover_artists);
  addArtistTags(props.song.original_artists);
  addTag(props.song.language_name);
  addTag(props.song.status_name);
  if (props.song.cover_date) {
    const dateForSearch = props.song.cover_date.replace(/-/g, "");
    addTag(dateForSearch, dateForSearch);
  }
  addTag(props.song.song_type);
  const uniqueTags = [];
  const seenValues = new Set();
  for (const tag of tags) {
    if (!seenValues.has(tag.value)) {
      uniqueTags.push(tag);
      seenValues.add(tag.value);
    }
  }
  return uniqueTags;
});

const openAddToPlaylistModal = () => {
  if (!authStore.isLoggedIn) {
    uni.showToast({ title: "请先登录", icon: "none" });
    return;
  }
  isAddToPlaylistModalVisible.value = true;
  closeMenu();
};

const openCommentModal = (options = {}) => {
  highlightParentId.value = options.parentId || null;
  highlightCommentId.value = options.commentId || null;
  isCommentModalVisible.value = true;
  closeMenu();
};

function formatDateWithWeekday(dateString) {
  if (!dateString) return "";
  const parts = dateString.split("-");
  const date = new Date(parts[0], parts[1] - 1, parts[2]);
  const weekdays = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}, ${weekdays[date.getDay()]}`;
}

const shareSong = async () => {
  const shareData = {
    title: `分享歌曲: ${props.song.title}`,
    text: `快来听听 ${props.song.cover_artists} 翻唱的《${props.song.title}》！`,
    url: `${window.location.origin}/#/pages/index/index?songId=${props.song.id}`,
  };
  if (navigator.share) {
    try {
      await navigator.share(shareData);
    } catch (err) {
      console.error("分享失败或被用户取消:", err);
    }
  } else {
    try {
      await navigator.clipboard.writeText(shareData.url);
      uni.showToast({ title: "浏览器不支持分享，链接已复制！", icon: "none" });
    } catch (err) {
      uni.showToast({ title: "复制链接失败", icon: "error" });
    }
  }
  closeMenu();
};

const closeMenu = () => {
  isMenuOpen.value = false;
  emit("menuToggled", { id: props.song.id, isOpen: false });
};

defineExpose({ closeMenu, openCommentModal });
</script>

<style lang="scss" scoped>
/* 样式保持不变 */
.cover-wrapper {
  position: relative;
  width: 60px;
  height: 60px;
  flex-shrink: 0;
  margin-right: 15px;
  cursor: pointer;
  border-radius: 8px;
  overflow: hidden;
}
.play-icon-wrapper {
  position: absolute; top: 0; left: 0; width: 100%; height: 100%;
  background-color: rgba(0, 0, 0, 0.3);
  display: flex; align-items: center; justify-content: center;
  opacity: 0;
  transition: opacity 0.2s ease-in-out;
}
.cover-wrapper:hover .play-icon-wrapper,
.cover-wrapper.active .play-icon-wrapper {
  opacity: 1;
}
.song-cover { width: 100%; height: 100%; }
.sound-wave-icon { display: flex; align-items: flex-end; height: 20px; }
.sound-wave-icon span {
  display: block; width: 3px; height: 100%; background-color: white; margin: 0 2px;
  animation: wave 1.2s infinite ease-in-out;
}
.sound-wave-icon span:nth-child(2) { animation-delay: 0.2s; }
.sound-wave-icon span:nth-child(3) { animation-delay: 0.4s; }
@keyframes wave {
  0%, 40%, 100% { transform: scaleY(0.4); }
  20% { transform: scaleY(1.0); }
}

.song-card-wrapper { position: relative; } 
.song-card { 
  display: flex; 
  align-items: center; 
  padding: 15px 0;
}
.song-info { flex-grow: 1; min-width: 0; }
.title { font-size: 18px; font-weight: 500; color: #333; margin: 0 0 5px 0; }
.artist-line { display: flex; align-items: center; font-size: 14px; color: #666; margin: 2px 0; }
.artist-separator { width: 16px; }
.meta { font-size: 12px; color: #999; margin-top: 5px; }
.meta span { margin-right: 8px; }

.actions { display: flex; align-items: center; margin-left: auto; padding-right: 5px; }
.action-item { display: flex; align-items: center; padding: 5px; cursor: pointer; border-radius: 6px; transition: background-color 0.2s; &:hover { background-color: #f5f5f5; } }
.like-icon { color: #888; transition: all 0.2s; }
.like-icon.liked { color: #e5245e; transform: scale(1.1); }
.likes-count { font-size: 14px; color: #666; margin-left: 5px; min-width: 20px; }
.menu-button { flex-shrink: 0; padding: 10px;  cursor: pointer; color: #888; border-radius: 50%; &:hover { background-color: #f5f5f5; color: #333; } }
.filter-menu { position: absolute; top: 50px; right: 0; width: 280px; background-color: white; border-radius: 8px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15); z-index: 1000; border: 1px solid #eee; display: flex; flex-direction: column; padding-bottom: 10px; }
.menu-header { padding: 12px 15px; font-weight: bold; border-bottom: 1px solid #f0f0f0; font-size: 16px; flex-shrink: 0; }
.tags-container { padding: 10px 0; max-height: 200px; overflow-y: auto; flex-grow: 1; }
.tag-item { display: flex; align-items: center; padding: 8px 15px; cursor: pointer; &:hover { background-color: #f9f9f9; } }
.tag-checkbox { margin-right: 15px; width: 16px; height: 16px; cursor: pointer; }
.tag-text { font-size: 15px; color: #333; }
.menu-item { display: flex; align-items: center; padding: 10px 15px; cursor: pointer; border-bottom: 1px solid #f0f0f0; &:hover { background-color: #f9f9f9; } }
.menu-item svg { margin-right: 10px; }
.menu-item span { font-size: 15px; }
.comment-item:hover {
  background-color: #f9f9f9;
}
.song-card.disabled {
  pointer-events: none;
  opacity: 0.7;
}

</style>